import tkinter as tk
from tkinter import ttk, scrolledtext
import threading
import time
import re
import logging

logger = logging.getLogger(__name__)


class TerminalExecution:
    def __init__(self, main_window):
        self.main_window = main_window
        self.terminal_notebook = None
        self.default_tab = None
        self.default_output = None

    def create_terminal_tabs(self):
        """创建终端标签页"""
        # 创建标签页
        self.terminal_notebook = ttk.Notebook(self.main_window.left_mid_frame)
        self.terminal_notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=0)

        # 默认标签页，用于显示系统消息
        self.default_tab = ttk.Frame(self.terminal_notebook)
        self.terminal_notebook.add(self.default_tab, text="系统消息")

        # 默认输出文本框
        self.default_output = scrolledtext.ScrolledText(self.default_tab, bg="black", fg="white")
        self.default_output.pack(fill=tk.BOTH, expand=True)
        self.default_output.insert(tk.END, "欢迎使用SSH服务器管理工具\n")
        self.default_output.config(state=tk.DISABLED)

    def show_message(self, message):
        """显示消息"""
        self.default_output.config(state=tk.NORMAL)
        self.default_output.insert(tk.END, f"{message}\n")
        self.default_output.see(tk.END)
        self.default_output.config(state=tk.DISABLED)
        logger.info(message)

    def execute_command(self, event=None):
        """执行命令到当前选中的服务器或批量执行到所有选中的服务器"""
        command = self.main_window.cmd_entry.get().strip()
        if not command:
            logger.warning("命令输入为空，不执行")
            return

        logger.info(f"执行命令: {command}")

        # 检查是否启用批量执行
        if self.main_window.batch_execute.get():
            # 获取所有选中且已连接的服务器
            selected_servers = []
            for item in self.main_window.server_connection.server_table.get_children():
                values = self.main_window.server_connection.server_table.item(item, "values")
                if values[0] == "√" and values[5] in ["已连接", "已连接(develop)", "已连接(缓存)"]:
                    ip = values[1]
                    if ip in self.main_window.server_connection.ssh_sessions:
                        selected_servers.append(ip)

            if not selected_servers:
                self.show_message("没有选中的已连接服务器，无法执行命令")
                logger.warning("批量执行命令：没有选中的已连接服务器")
                return

            # 创建执行结果提示
            self.show_message(f"批量执行命令: {command} (在 {len(selected_servers)} 台服务器上)")
            logger.info(f"开始批量执行命令: \"{command}\" 在 {len(selected_servers)} 台服务器上")

            # 记录执行命令时间
            cmd_time = time.strftime("%H:%M:%S")

            # 多线程执行命令
            for ip in selected_servers:
                # 在新线程中执行命令
                threading.Thread(target=self.run_command, args=(ip, command)).start()

            # 清空命令输入框
            self.main_window.cmd_entry.delete(0, tk.END)
            return

        else:
            # 单服务器执行 - 获取当前选中的标签页
            current_tab = self.terminal_notebook.tab(self.terminal_notebook.select(), "text")
            if current_tab.startswith("终端-"):
                ip = current_tab.replace("终端-", "")
                if ip in self.main_window.server_connection.ssh_sessions:
                    threading.Thread(target=self.run_command, args=(ip, command)).start()
                else:
                    self.show_message("没有选中的已连接服务器，无法执行命令")
                    logger.warning(f"没有选中的已连接服务器 {ip}，无法执行命令")
                    return
            self.main_window.cmd_entry.delete(0, tk.END)

    def run_command(self, ip, command):
        """在指定服务器上执行命令"""
        ssh_session = self.main_window.server_connection.ssh_sessions[ip]
        shell = ssh_session['shell']
        item_id = ssh_session['item_id']

        try:
            # 更新命令执行状态
            self.main_window.server_connection.update_server_status(item_id, f"执行: {command}", 7)

            # 发送命令到shell
            shell.send(f"{command}\n")

            # 等待命令输出
            time.sleep(0.5)

            # 循环接收输出直到命令执行完毕
            output = ""
            timeout = time.time() + 15  # 15秒超时

            while time.time() < timeout:
                if shell.recv_ready():
                    chunk = shell.recv(4096).decode("utf-8", errors="ignore")
                    output += chunk
                    self.main_window.server_connection.append_to_terminal(ip, chunk)
                    timeout = time.time() + 5  # 每次收到数据延长超时
                else:
                    time.sleep(0.1)

                    # 检查是否遇到交互式提示(如sudo密码请求)
                    if "password" in output.lower() and ":" in output and output.rstrip().endswith(":"):
                        # 让用户在GUI中处理
                        self.main_window.server_connection.update_server_status(item_id, f"等待输入密码...", 7)
                        break

                    # 检查命令是否已完成的一种启发式方法
                    # 如果输出结束有shell提示符(如 user@host:~$)，则认为命令已完成
                    if re.search(r'[\r\n][a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+:[~\w/]*[$#]\s*$', output):
                        break

            # 更新命令执行状态
            self.main_window.server_connection.update_server_status(item_id, "完成", 7)
            logger.info(f"命令 \"{command}\" 在 {ip} 上执行完成")

        except Exception as e:
            self.main_window.server_connection.append_to_terminal(ip, f"\n执行命令时出错: {str(e)}\n")
            self.main_window.server_connection.update_server_status(item_id, f"失败: {str(e)[:20]}...", 7)
            logger.error(f"在 {ip} 上执行命令 \"{command}\" 失败: {e}", exc_info=True) 